package com.lab.interceptor;

import com.lab.common.BusinessException;
import com.lab.common.JwtProperties;
import com.lab.common.JwtUtil;
import com.lab.common.RoleConstant;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
@Slf4j
public class JwtAuthInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtProperties jwtProperties;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String uri = request.getRequestURI();
        log.info("拦截请求：{}", uri);

        // 1. 放行登录接口
        if (uri.contains("/login")) {
            return true;
        }

        // 2. 获取token
        String token = request.getHeader("token");
        if (token == null || token.trim().isEmpty()) {
            log.warn("请求{}未携带token", uri);
            throw new BusinessException(401, "请先登录获取token");
        }

        // 3. 解析token获取角色（逐个尝试密钥，确保正确解析）
        String role = null;
        Claims claims = null;

        // 尝试管理员密钥
        try {
            claims = JwtUtil.parseJWT(jwtProperties.getAdmin().getSecretKey(), token);
            role = claims.get("role", String.class);
            request.setAttribute(com.lab.common.JwtClaimsConstant.USER_ID, claims.get(com.lab.common.JwtClaimsConstant.USER_ID, Integer.class));
            log.info("使用管理员密钥解析成功，角色：{}", role);
        } catch (Exception e) {
            // 尝试教师密钥
            try {
                claims = JwtUtil.parseJWT(jwtProperties.getTeacher().getSecretKey(), token);
                role = claims.get("role", String.class);
                request.setAttribute(com.lab.common.JwtClaimsConstant.USER_ID, claims.get(com.lab.common.JwtClaimsConstant.USER_ID, Integer.class));
                log.info("使用教师密钥解析成功，角色：{}", role);
            } catch (Exception ex) {
                // 尝试学生密钥
                try {
                    claims = JwtUtil.parseJWT(jwtProperties.getStudent().getSecretKey(), token);
                    role = claims.get("role", String.class);
                    request.setAttribute(com.lab.common.JwtClaimsConstant.USER_ID, claims.get(com.lab.common.JwtClaimsConstant.USER_ID, Integer.class));
                    log.info("使用学生密钥解析成功，角色：{}", role);
                } catch (Exception exc) {
                    log.error("token解析失败：{}", exc.getMessage());
                    throw new BusinessException(401, "token无效或已过期");
                }
            }
        }

        // 4. 校验角色与路径匹配
        if (!checkRole(role, uri)) {
            log.warn("角色{}无权访问{}", role, uri);
            throw new BusinessException(403, "无权限访问该接口");
        }

        // 5. 校验通过，放行
        return true;
    }

    // 校验角色与路径是否匹配
    private boolean checkRole(String role, String uri) {
        if (uri.startsWith("/admin/")) {
            return RoleConstant.ADMIN.equals(role);
        } else if (uri.startsWith("/teacher/")) {
            return RoleConstant.TEACHER.equals(role);
        } else if (uri.startsWith("/student/")) {
            return RoleConstant.STUDENT.equals(role);
        }
        return false; // 非角色路径直接拦截（可选）
    }
}